package com.unicom.office.impl;

import com.unicom.office.config.OfficeConfig;
import com.unicom.office.node.*;
import com.unicom.office.parser.ExcelParser;
import com.unicom.office.parser.OfficeSyntaxParser;
import com.unicom.office.runtime.OfficeRuntime;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.wp.usermodel.Paragraph;
import org.apache.poi.xssf.usermodel.*;

import java.io.FileInputStream;
import java.util.Iterator;
import java.util.List;

public class XlsxParser extends ExcelParser {
    public XlsxParser(){
        super(null, null);
    }

    public XlsxParser(OfficeConfig config, OfficeRuntime runtime) {
        super(config, runtime);
    }

    public Object getSource(String sourcePath) {
        try {
            FileInputStream fileInputStream = new FileInputStream(sourcePath);
            String extString = sourcePath.substring(sourcePath.lastIndexOf("."));
            if (".xlsx".equals(extString)) {
                return new XSSFWorkbook(fileInputStream);
            } else {
                throw new RuntimeException("文件格式错误");
            }
        }catch(Exception ex){
            throw new RuntimeException(ex.getMessage());
        }
    }

    protected OfficeNodeType parseType(Object source) {
        if(source instanceof Workbook){
            return OfficeNodeType.Workbook;
        }else if(source instanceof Sheet){
            return OfficeNodeType.Worksheet;
        }else if(source instanceof XSSFTextBox){
            return OfficeNodeType.Textbox;
        }else if(source instanceof Row){
            return OfficeNodeType.Row;
        }else if(source instanceof Cell){
            return OfficeNodeType.Cell;
        }else if(source instanceof Paragraph){
            return OfficeNodeType.Paragraph;
        }else{
            throw new RuntimeException("无法解析的节点");
        }
    }

    protected WorkbookNode parseWorkbook(Object source) {
        Workbook workbook = (Workbook) source;
        WorkbookNode workbookNode = new WorkbookNode(source);

        Iterator<Sheet> sheetIterator = workbook.sheetIterator();
        while (sheetIterator.hasNext()){
            Sheet sheet = sheetIterator.next();
            parseWorksheet(sheet, workbookNode);
        }

        return workbookNode;
    }

    protected WorksheetNode parseWorksheet(Object source, OfficeNode parentNode) {
        XSSFSheet sheet = (XSSFSheet) source;
        WorksheetNode worksheetNode = new WorksheetNode(source);
        parentNode.addChild(worksheetNode);

        int lastRowNum = sheet.getLastRowNum();
        for (int i = 0; i <= lastRowNum; i++) {
            Row row = sheet.getRow(i);
            parseRow(row, worksheetNode);
        }

//        Iterator<Row> rowIterator = sheet.rowIterator();
//        while (rowIterator.hasNext()){
//            Row row = rowIterator.next();
//            if(parentNode.getChildren().size() < row.getRowNum() + 1) {
//                parseRow(sheet.getRow())
//                worksheetNode.addChild(new RowNode(null));
//            }
//            parseRow(row, worksheetNode);
//        }

        // 解析textbox应该在此处
        XSSFDrawing drawingPatriarch = sheet.getDrawingPatriarch();
        if(drawingPatriarch != null) {
            List<XSSFShape> shapes = drawingPatriarch.getShapes();
            for (XSSFShape shape : shapes) {
                if(shape instanceof XSSFSimpleShape){
                    TextboxNode textboxNode = parseTextbox(shape, worksheetNode);
                    //worksheetNode.addTextbox(textboxNode);
                }
            }
        }

        return worksheetNode;
    }

    protected TextboxNode parseTextbox(Object source, OfficeNode parentNode) {
        XSSFSimpleShape textBox = (XSSFSimpleShape)source;
        TextboxNode textboxNode = new TextboxNode(source);

        for (XSSFTextParagraph textParagraph : textBox.getTextParagraphs()) {
            parseParagraph(textParagraph, textboxNode);
        }

        return textboxNode;
    }

    protected RowNode parseRow(Object source, OfficeNode parentNode) {
        Row row = (Row) source;
        RowNode rowNode = new RowNode(source);
        parentNode.addChild(rowNode);

        if(row == null){
            return rowNode;
        }

        short lastCellNum = row.getLastCellNum();
        for (int i = 0; i <= lastCellNum; i++) {
            Cell cell = row.getCell(i);
            parseCell(cell, rowNode);
        }

//        Iterator<Cell> cellIterator = row.cellIterator();
//        while(cellIterator.hasNext()){
//            Cell cell = cellIterator.next();
//            parseCell(cell, rowNode);
//        }

        return rowNode;
    }

    protected CellNode parseCell(Object source, OfficeNode parentNode) {
        Cell cell = (Cell)source;
        CellNode cellNode = new CellNode(source);
        parentNode.addChild(cellNode);

        if(cell == null){
            return cellNode;
        }

//        // 添加样式设置
//        OfficeCellStype style = new OfficeCellStype();
//        ProcNode procNode = new ProcNode(TemplateProc.CELL_STYLE);
//        procNode.addParam(style);
//        cellNode.addProc(procNode);

        if(cell.getCellType() == CellType.STRING) {
            // 使用富文本
            XSSFRichTextString rich = (XSSFRichTextString) cell.getRichStringCellValue();
            parseRichText(rich, cellNode);
        }else if(cell.getCellType() == CellType.NUMERIC) {
            cellNode.setText(String.valueOf(cell.getNumericCellValue()), true);
        }

        return cellNode;
    }

    private ParagraphNode parseRichText(RichTextString richTextString, OfficeNode parentNode){
        XSSFRichTextString rich = (XSSFRichTextString) richTextString;
        String str = rich.toString();
        ParagraphNode paragraphNode = new ParagraphNode(richTextString);
        parentNode.addChild(paragraphNode);

        XSSFFont font = null;
        int i = 0;
        TextRangeNode textRangeNode = null;

        while (i < str.length()){
            XSSFFont fontAtIndex = rich.getFontAtIndex(i);
            if(fontAtIndex != null && fontAtIndex == font) {
                textRangeNode.appendChar(str.charAt(i));
            }else {
                textRangeNode = new TextRangeNode(fontAtIndex);
                textRangeNode.setText(str.charAt(i), false);
                paragraphNode.addChild(textRangeNode);
            }
            font = fontAtIndex;
            i++;
        }

        // 开始语法解析
        OfficeSyntaxParser syntaxParser = new OfficeSyntaxParser(paragraphNode, config);
        syntaxParser.parse();

        return paragraphNode;
    }

    protected ParagraphNode parseParagraph(Object source, OfficeNode parentNode) {
        XSSFTextParagraph paragraph = (XSSFTextParagraph)source;
        ParagraphNode paragraphNode = new ParagraphNode(source);
        parentNode.addChild(paragraphNode);

        for (XSSFTextRun textRun : paragraph.getTextRuns()) {
            TextRangeNode textRangeNode = new TextRangeNode(textRun);
            textRangeNode.setText(textRun.getText(), false);
            textRangeNode.setTextStype(new OfficeTextStype());
            textRangeNode.getTextStype().setBold(textRun.isBold());
            textRangeNode.getTextStype().setColor(textRun.getFontColor());
            paragraphNode.addChild(textRangeNode);
        }

        // 开始语法解析
        OfficeSyntaxParser syntaxParser = new OfficeSyntaxParser(paragraphNode, config);
        syntaxParser.parse();

        return paragraphNode;
    }

    protected TextRangeNode parseTextRange(Object source, OfficeNode parentNode) {
        return null;
    }

    protected PictureNode parsePicture(Object source, OfficeNode parentNode) {
        return null;
    }
}
